package com.googlecode.bip.entity.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.TimeZone;
import com.googlecode.bip.entity.IUser;
import com.googlecode.bip.entity.Role;
import cx.ath.choisnet.sql.SQLTools;

/**
 * Default implementation of @{@link IUser} ({@link com.googlecode.bip.entity.Role#BIP_USER})
 */
public class BipUser implements IUser
{
    private static final long serialVersionUID = 1L;
    private int         iduser;
    private String      username;
    private int         isactive;
    private String      idlocal;
    private TimeZone    timeZone;
    private String      userMail;
    private String      userDescription;

    /**
     * Create a NOT initialized User
     */
    public BipUser()
    {
        // empty
    }

    /**
     * Create a shadow copy of giving User
     *
     * @param o User to clone
     */
    public BipUser( final BipUser o )
    {
        this.iduser             = o.iduser;
        this.username           = o.username;
        this.isactive           = o.isactive;
        this.idlocal            = o.idlocal;
        this.timeZone           = o.timeZone;
        this.userMail           = o.userMail;
        this.userDescription    = o.userDescription;
    }

    /**
     *
     * @param rSet
     * @return
     * @throws SQLException
     */
    public BipUser set( final ResultSet rSet ) throws SQLException
    {
        this.iduser   = rSet.getInt( "iduser" );
        this.username = rSet.getString( "username" );
        this.isactive = rSet.getInt( "isactive" );
        this.idlocal  = rSet.getString( "idlocal" );

        final String timezoneid = rSet.getString( "timezone" );

        if( timezoneid == null ) {
            this.timeZone = null;
            }
        else {
            this.timeZone = TimeZone.getTimeZone( timezoneid );
            }

        this.userMail        = EntityHelper.getNotEmptyValue( rSet.getString( "usermail" ) );
        this.userDescription = EntityHelper.getNotEmptyValue( rSet.getString( "userdescription" ) );

        return this;
    }

    /**
     * Returns the iduser for this user (ReadOnly)
     * @return the iduser
     */
    @Override
    public int getIdUser()
    {
        return iduser;
    }

    /**
     * <p>ReadOnly</p>
     *
     * @param iduser the iduser to set
     */
    public void protected_setIdUser( int iduser )
    {
        this.iduser = iduser;
    }

    /**
     * Returns the username for this user
     * @return the username
     */
    @Override
    public String getUserName()
    {
        return username;
    }

    @Override
    public boolean isInRole( Role role )
    {
        return Role.BIP_USER.equals( role );
    }

    /**
     * Normalized, validate then set the username for this user
     * @param username the username to set
     */
    @Override
    public void setUsername( final String username )
    {
        final String uname = username.trim().toLowerCase();

        if( uname.length() == 0 && uname.length() > 63 ) {
            throw new IllegalArgumentException( "Bad length: " + uname.length() );
            }
        if( ! EntityHelper.isValidAlphanumericNoWhiteSpaces( uname ) ) {
            throw new IllegalArgumentException( "Bad content" );
        }

        //TODO: improve check BIP_USER username

        this.username = uname;
    }

    /**
     * @return the isactive
     */
    @Override
    public int getIsActive()
    {
        return isactive;
    }

    /**
     * @param isactive the isactive to set
     */
    @Override
    public void setIsActive( int isactive )
    {
        // TODO: check value
        this.isactive = isactive;
    }

    /**
     * @return the idlocal
     */
    @Override
    public String getIdLocal()
    {
        return idlocal;
    }

    /**
     * @param idlocal the idlocal to set
     */
    @Override
    public void setIdlocal( String idlocal )
    {
        // TODO: check value idlocal for user (look for rules)
        this.idlocal = idlocal;
    }

    @Override
    public TimeZone getTimeZone()
    {
        return this.timeZone;
    }

    /**
     * Returns SQL formatted String for {@link #getTimeZone()} value
     * @return SQL formatted String for {@link #getTimeZone()} value (could be null)
     */
    public String formatTimeZone()
    {
        if( this.timeZone != null ) {
            return SQLTools.parseFieldValue( this.timeZone.getID() );
            }
        else {
            return null;
            }
    }

    @Override
    public void setTimeZone( TimeZone tz )
    {
        this.timeZone = tz;
    }

    @Override
    public String getEMail()
    {
        return this.userMail;
    }

    @Override
    public void setEMail( final String email )
    {
        this.userMail = EntityHelper.getNotEmptyValue( email );
    }

    @Override
    public String getUserDescription()
    {
        return this.userDescription;
    }

    @Override
    public void setUserDescription( final String userDescription )
    {
        this.userDescription = EntityHelper.getNotEmptyValue( userDescription );
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((idlocal == null) ? 0 : idlocal.hashCode());
        result = prime * result + iduser;
        result = prime * result + isactive;
        result = prime * result
                + ((timeZone == null) ? 0 : timeZone.hashCode());
        result = prime * result
                + ((userDescription == null) ? 0 : userDescription.hashCode());
        result = prime * result
                + ((userMail == null) ? 0 : userMail.hashCode());
        result = prime * result
                + ((username == null) ? 0 : username.hashCode());
        return result;
    }

    @Override
    public boolean equals( Object obj )
    {
        if( this == obj ) {
            return true;
        }
        if( obj == null ) {
            return false;
        }
        if( !(obj instanceof BipUser) ) {
            return false;
        }
        BipUser other = (BipUser)obj;
        if( idlocal == null ) {
            if( other.idlocal != null ) {
                return false;
            }
        } else if( !idlocal.equals( other.idlocal ) ) {
            return false;
        }
        if( iduser != other.iduser ) {
            return false;
        }
        if( isactive != other.isactive ) {
            return false;
        }
        if( timeZone == null ) {
            if( other.timeZone != null ) {
                return false;
            }
        } else if( !timeZone.equals( other.timeZone ) ) {
            return false;
        }
        if( userDescription == null ) {
            if( other.userDescription != null ) {
                return false;
            }
        } else if( !userDescription.equals( other.userDescription ) ) {
            return false;
        }
        if( userMail == null ) {
            if( other.userMail != null ) {
                return false;
            }
        } else if( !userMail.equals( other.userMail ) ) {
            return false;
        }
        if( username == null ) {
            if( other.username != null ) {
                return false;
            }
        } else if( !username.equals( other.username ) ) {
            return false;
        }
        return true;
    }

    @Override
    public String toString()
    {
        return "BipUser [iduser=" + iduser
                + ", username=" + username
                + ", isactive=" + isactive
                + ", idlocal=" + idlocal
                + ", timeZone=" + timeZone
                + ", userMail=" + userMail
                + ", userDescription=" + userDescription
                + "]";
    }

}
